# -*- coding: utf-8 -*-
import unittest
import os.path

from kivy.lang import Builder
from model.gamestate import *
from guess_word import GuessWordScreen
from presenter_mock import PresenterMock


class GuessWordTest(unittest.TestCase):
    def setUp(self):
        player = Player(u'aaa', [])
        self.Words = [Word(player, u'Семиотика'), Word(player, u'Слово'),
                      Word(player, u'Кастрюлька'), Word(player, u'Шляпа')]
        self.hat = Hat(self.Words)
        self.GameRound = GameRound(5, [], None, None)
        self.Settings = Settings(10, 20)
        self.gamestate = GameState(None, self.hat, self.GameRound, None,
                                   None, None, self.Settings)
        Builder.load_file(os.path.join(os.path.dirname(__file__),
                                       'guesswordscreen.kv'))

    def test_guessed_button(self):
        self.presenter = PresenterMock(Phase.GUESS_WORD)
        widget = GuessWordScreen(self.gamestate, self.presenter)
        WordsLen = len(widget.gamestate.hat.words)
        OldWord = widget.gamestate.game_round.current_word
        widget.guessed()
        NewWord = widget.gamestate.game_round.words[-1]
        self.assertEqual(OldWord.text, NewWord.word.text)
        self.assertEqual(WordGuessResult.GUESS, NewWord.result)
        self.assertEqual(NewWord.time, 15)
        NewLen = len(widget.gamestate.hat.words)
        self.assertFalse(self.presenter.is_phase_changed)
        self.assertEqual(WordsLen - 1, NewLen)

    def test_fail_button(self):
        self.presenter = PresenterMock(Phase.RESULTS_OF_ONE_PAIR)
        widget = GuessWordScreen(self.gamestate, self.presenter)
        OldWord = widget.gamestate.game_round.current_word
        widget.fail()
        NewWord = widget.gamestate.game_round.words[-1]
        self.assertEqual(OldWord.text, NewWord.word.text)
        self.assertEqual(WordGuessResult.FAIL, NewWord.result)
        self.assertEqual(NewWord.time, 15)
        self.assertEqual(self.presenter.is_phase_changed, True)

    def test_put_back_inf_button(self):
        self.presenter = PresenterMock(Phase.GUESS_WORD)
        self.presenter.settings.game.skip_words = 2
        widget = GuessWordScreen(self.gamestate, self.presenter)
        WordsLen = len(widget.gamestate.hat.words)
        OldWord = widget.gamestate.game_round.current_word

        skips_left_before = widget.skip_words_left
        widget.put_back()
        skips_left_after = widget.skip_words_left

        NewWord = widget.gamestate.game_round.words[-1]
        NewLen = len(widget.gamestate.hat.words)
        self.assertFalse(self.presenter.is_phase_changed)
        self.assertEqual(WordsLen, NewLen)
        self.assertEqual(OldWord.text, NewWord.word.text)
        self.assertEqual(WordGuessResult.PUT_BACK, NewWord.result)
        self.assertEqual(NewWord.time, 15)
        self.assertEqual(skips_left_before, skips_left_after)

    def test_put_back_one_button(self):
        self.presenter = PresenterMock(Phase.GUESS_WORD)
        self.presenter.settings.game.skip_words = 1
        widget = GuessWordScreen(self.gamestate, self.presenter)
        WordsLen = len(widget.gamestate.hat.words)
        OldWord = widget.gamestate.game_round.current_word

        skips_left_before = widget.skip_words_left
        widget.put_back()
        skips_left_after = widget.skip_words_left

        NewWord = widget.gamestate.game_round.words[-1]
        NewLen = len(widget.gamestate.hat.words)
        self.assertFalse(self.presenter.is_phase_changed)
        self.assertEqual(WordsLen, NewLen)
        self.assertEqual(OldWord.text, NewWord.word.text)
        self.assertEqual(WordGuessResult.PUT_BACK, NewWord.result)
        self.assertEqual(skips_left_before - 1, skips_left_after)

    def test_put_back_zero_button(self):
        self.presenter = PresenterMock(Phase.GUESS_WORD)
        self.presenter.settings.game.skip_words = 0
        widget = GuessWordScreen(self.gamestate, self.presenter)
        WordsLen = len(widget.gamestate.hat.words)
        OldWord = widget.gamestate.game_round.current_word

        skips_left_before = widget.skip_words_left
        widget.put_back()
        skips_left_after = widget.skip_words_left

        self.assertEqual(len(widget.gamestate.game_round.words), 0)
        self.assertFalse(self.presenter.is_phase_changed)
        self.assertEqual(skips_left_before, skips_left_after)

    def test_end_game_nowords(self):
        self.presenter = PresenterMock(Phase.RESULTS_OF_ONE_PAIR)
        self.gamestate.hat.words = [Word(Player(u'Sasha', []), u'Masha')]
        widget = GuessWordScreen(self.gamestate, self.presenter)
        widget.guessed()
        self.assertEqual(self.presenter.is_phase_changed, True)

    def test_end_game_by_timer(self):
        self.presenter = PresenterMock(Phase.RESULTS_OF_ONE_PAIR)
        self.gamestate.hat.words = [Word(Player(u'Sasha', []), u'Masha')]
        widget = GuessWordScreen(self.gamestate, self.presenter)
        old_word = widget.gamestate.game_round.current_word
        widget.update(4)
        self.assertEqual(len(self.gamestate.game_round.words), 0)
        self.assertTrue(widget.is_last_second)
        widget.update(1)
        self.assertTrue(widget.is_time_out)
        new_word = widget.gamestate.game_round.current_word
        self.assertEqual(old_word, new_word)
        self.assertFalse(self.presenter.is_phase_changed)
        widget.guessed()
        self.assertTrue(self.presenter.is_phase_changed)
        self.assertEqual(len(self.gamestate.game_round.words), 1)
        new_word = widget.gamestate.game_round.words[-1]
        self.assertEqual(old_word, new_word.word)
        self.assertEqual(WordGuessResult.GUESS, new_word.result)

if __name__ == '__main__':
    unittest.main()
